import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;


public class Model implements Subject
{
	ArrayList<Observer> observers = new ArrayList<Observer>(); 
	
	ArrayList<College> colleges;
	GoogleParser googleparser;
	HTMLRetriever htmlretriever;
	HttpClient httpclient;
	Faculty selected1, selected2;
	Context firstContext, secondContext;
	Strategy firstStrategy, secondStrategy;
	StringBuffer stafflist, query;
	
	public Model()
	{
		this.colleges = new ArrayList<College>();
		this.setColleges(loadColleges());
		this.colleges.trimToSize();
		this.stafflist = new StringBuffer("");
		this.htmlretriever = new HTMLRetriever();
		this.httpclient = new HttpClient();
	}
	
	public void setColleges(ArrayList<College> loadedColleges)
	{
		this.colleges = loadedColleges;
	}
	
	public Faculty getFaculty(String college, String fac)
	{
		Faculty f = new Faculty();
		Iterator<College> it = colleges.iterator();
		while(it.hasNext()) 
		{
			College temp = it.next();
			if(temp.getCollegeName().equals(college))
			{
				Iterator<Faculty> iter = temp.getSchools().iterator();
				while(iter.hasNext())
				{
					Faculty tmp = iter.next();
					if(tmp.getName().equals(fac))
					{
						f = tmp;
						break;
					}
				}
			}
		}
		
		return f;
	}
	
	public void saveColleges()
	{
		try
		{
			FileOutputStream fileout = new FileOutputStream("ranker.dat");
			ObjectOutputStream objout = new ObjectOutputStream(fileout);
			objout.writeObject(colleges);
			objout.flush();
			objout.close();
			fileout.close();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}

	public void addFaculty(String college, String faculty, String address, String field)
	{
		Faculty fac = new Faculty();
		fac.setName(faculty);
		fac.setAddress(address);
		fac.setType(field);
		
		boolean alreadyThere = false;
		for(int i = 0; i<colleges.size(); i++)
		{
			if(colleges.get(i).getCollegeName().equals(college))
			{
				alreadyThere = true;
				if(!colleges.get(i).contains(faculty))
				{
					System.out.println("adding faculty to existing College");
					colleges.get(i).addSchool(fac);
				}
			}
		}
		if(!alreadyThere)
		{
			College c = new College();
			c.setCollegeName(college);
			System.out.println("adding faculty to new College");
			c.addSchool(fac);
			colleges.add(c);
		}
		
		System.out.println("notifying");
		colleges.trimToSize();
		notifyObservers();
	}
	
	public void printAll()
	{
		Iterator<College> it = colleges.iterator();
		while(it.hasNext()) 
		{
			College c = it.next();
			System.out.println(c.getCollegeName());
			c.printAll();
			System.out.println("==================");
		}
	}
		
	@SuppressWarnings("unchecked")
	public static ArrayList<College> loadColleges()
	{
		ArrayList<College> saved = new ArrayList<College>();
		
		try
		{
			File f = new File("ranker.dat");
			boolean success = f.createNewFile();

			if(!success && f.length() != 0)
			{
				FileInputStream filein = new FileInputStream(f);
				ObjectInputStream objin = new ObjectInputStream(filein);
				saved = (ArrayList<College>)objin.readObject();
				objin.close();
				filein.close();
			}
		}
		catch(FileNotFoundException e)
		{
			System.out.println("File not found...");
			e.printStackTrace();
		}
		catch(IOException e)
		{
			System.out.println("I/O Exception...");
			e.printStackTrace();
		}
		catch(ClassNotFoundException e)
		{
			System.out.println("Stay classy, java...");
			e.printStackTrace();
		}
		return saved;
		
	}

	public void setSelected(Faculty first, Faculty second)
	{
		this.selected1 = first;
		this.selected2 = second;
	}
	
	public void setFirst(Faculty fac)
	{
		this.selected1 = fac;
	}
	
	public void setSecond(Faculty fac)
	{
		this.selected2 = fac;
	}
	
	public String getFacultysCollege(Faculty fac)
	{

		Iterator<College> it = colleges.iterator();
		while(it.hasNext()) 
		{
			College c = it.next();
			Iterator<Faculty> iter2 = c.getSchools().iterator();
			while(iter2.hasNext()) 
			{
				Faculty f = iter2.next();
				if(f.getName().equals(fac.getName()))
				{
					return c.getCollegeName();
				}
			}
		}

		return "";
	}
	
	public String getInitials(String str)
	{
		//get initials by taking first char & every one preceded by whitespace
		int of = str.indexOf(" of");
		String temp = "";
		if(of != -1)
		{
			temp += str.substring(0, of);
			temp += str.substring(of + 3);
			
			str = temp;
		}
		String newStr = "";
		newStr += str.charAt(0);
		for(int i = 1; i<str.length(); i++)
		{
			if(str.length() >= (i+1) && Character.isWhitespace(str.charAt(i)))
			{
				newStr+= str.charAt(i+1);
			}
		}
		return newStr;
	}
	
	/* (non-Javadoc)
	 * @see Subject#addObserver(Observer)
	 */
	@Override
	public void addObserver(Observer o) 
	{
		observers.add(o);
	}

	/* (non-Javadoc)
	 * @see Subject#removeObserver(Observer)
	 */
	@Override
	public void removeObserver(Observer o) 
	{
		observers.remove(o);
	}
	
	public void notifyObservers() 
	{
		Iterator<Observer> i = observers.iterator();
		while (i.hasNext()) 
		{
			Observer o = i.next();
			o.update(this);
		}
	}



	/* (non-Javadoc)
	 * @see Subject#getColleges()
	 */
	@Override
	public ArrayList<College> getColleges() 
	{
		return this.colleges;
	}


	/**
	 * 
	 */
	public void reset() 
	{
		// TODO Auto-generated method stub
	}

}